from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Avg
import json
import random
from .models import Level, Question, QuestionOption, UserAnswer, UserScore
from backed.pagination import get_pagination_params, paginate_queryset


@csrf_exempt
@require_http_methods(["GET"])
def level_list_view(request):
    """
    获取关卡列表
    GET /xiangsu/challenge/levels/
    """
    try:
        qs = Level.objects.all().order_by('level_id')
        page, page_size = get_pagination_params(request, default_page_size=10, max_page_size=100)
        levels, meta = paginate_queryset(qs, page, page_size)
        level_ids = [l.level_id for l in levels]
        question_counts_qs = Question.objects.filter(level_id__in=level_ids).values('level_id').annotate(cnt=Count('question_id'))
        question_counts = {row['level_id']: row['cnt'] for row in question_counts_qs}
        answered_counts = {}
        correct_counts = {}
        if request.user.is_authenticated:
            answered_qs = UserAnswer.objects.filter(user=request.user, question__level_id__in=level_ids).values('question__level_id').annotate(answered_count=Count('question', distinct=True))
            correct_qs = UserAnswer.objects.filter(user=request.user, question__level_id__in=level_ids, is_correct=True).values('question__level_id').annotate(correct_count=Count('answer_log_id'))
            answered_counts = {row['question__level_id']: row['answered_count'] for row in answered_qs}
            correct_counts = {row['question__level_id']: row['correct_count'] for row in correct_qs}
        level_data = []
        for level in levels:
            q_total = question_counts.get(level.level_id, 0)
            if request.user.is_authenticated:
                a_count = answered_counts.get(level.level_id, 0)
                c_count = correct_counts.get(level.level_id, 0)
                level_data.append({
                    'level_id': level.level_id,
                    'level_name': level.level_name,
                    'total_questions': q_total,
                    'answered_questions': a_count,
                    'correct_answers': c_count,
                    'completion_rate': round((a_count / q_total) * 100, 2) if q_total > 0 else 0,
                    'accuracy_rate': round((c_count / a_count) * 100, 2) if a_count > 0 else 0
                })
            else:
                level_data.append({
                    'level_id': level.level_id,
                    'level_name': level.level_name,
                    'total_questions': q_total,
                    'answered_questions': 0,
                    'correct_answers': 0,
                    'completion_rate': 0,
                    'accuracy_rate': 0
                })
        
        return JsonResponse({
            'success': True,
            'data': {
                'items': level_data,
                'meta': meta
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取关卡列表失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
def level_detail_view(request, level_id):
    """
    获取关卡详情和题目列表
    GET /xiangsu/challenge/levels/{level_id}/
    """
    try:
        level = Level.objects.get(level_id=level_id)
        
        # 获取该关卡的题目并分页
        qs = Question.objects.filter(level=level).order_by('question_id')
        page, page_size = get_pagination_params(request, default_page_size=10, max_page_size=100)
        questions, meta = paginate_queryset(qs, page, page_size)
        q_ids = [q.question_id for q in questions]
        options_qs = QuestionOption.objects.filter(question_id__in=q_ids).order_by('option_id').values('option_id', 'content', 'question_id')
        options_map = {}
        for row in options_qs:
            options_map.setdefault(row['question_id'], []).append({'option_id': row['option_id'], 'content': row['content']})
        question_data = []
        for question in questions:
            option_data = options_map.get(question.question_id, [])
            question_data.append({
                'question_id': question.question_id,
                'content': question.content,
                'options': option_data
            })
        
        level_info = {
            'level_id': level.level_id,
            'level_name': level.level_name,
            'questions': question_data,
        }
        return JsonResponse({
            'success': True,
            'data': {
                'level': level_info,
                'meta': meta
            }
        })
        
    except Level.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '关卡不存在'
        }, status=404)
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取关卡详情失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
def question_detail_view(request, question_id):
    """
    获取单个题目详情
    GET /xiangsu/challenge/questions/{question_id}/
    """
    try:
        question = Question.objects.get(question_id=question_id)
        
        # 获取题目选项
        options = QuestionOption.objects.filter(question=question).order_by('option_id')
        
        option_data = [{
            'option_id': option.option_id,
            'content': option.content
        } for option in options]
        
        question_info = {
            'question_id': question.question_id,
            'level_id': question.level.level_id,
            'level_name': question.level.level_name,
            'content': question.content,
            'options': option_data
        }
        
        return JsonResponse({
            'success': True,
            'data': question_info
        })
        
    except Question.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '题目不存在'
        }, status=404)
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取题目详情失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
def random_question_view(request):
    """
    获取随机题目
    GET /xiangsu/challenge/questions/random/

    可选查询参数:
    - level_id: 仅从指定关卡选择题目
    - difficulty: 难度标签（简单/中等/困难）
    - exclude_answered: 若登录用户，排除已答过的题目（1/true）
    """
    try:
        level_id = request.GET.get('level_id')
        difficulty = request.GET.get('difficulty')
        exclude_answered = request.GET.get('exclude_answered')
        exclude_answered = str(exclude_answered).lower() in ('1', 'true', 'yes')

        qs = Question.objects.all()
        if level_id:
            qs = qs.filter(level_id=level_id)
        if difficulty:
            qs = qs.filter(difficulty_label=difficulty)

        if exclude_answered and request.user.is_authenticated:
            answered_q_ids = UserAnswer.objects.filter(user=request.user).values_list('question_id', flat=True)
            qs = qs.exclude(question_id__in=list(answered_q_ids))

        total = qs.count()
        if total == 0:
            return JsonResponse({
                'success': False,
                'message': '未找到符合条件的题目'
            }, status=404)

        rand_index = random.randint(0, total - 1)
        question = qs.order_by('question_id')[rand_index]

        options = QuestionOption.objects.filter(question=question).order_by('option_id')
        option_data = [{
            'option_id': opt.option_id,
            'content': opt.content
        } for opt in options]

        data = {
            'question_id': question.question_id,
            'level_id': question.level.level_id,
            'level_name': question.level.level_name,
            'content': question.content,
            'options': option_data
        }

        return JsonResponse({
            'success': True,
            'data': data
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取随机题目失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["POST"])
@login_required
def submit_answer_view(request):
    """
    提交答题答案
    POST /xiangsu/challenge/submit/
    
    请求参数: {
        "question_id": 题目ID,
        "selected_option_id": 用户选择的选项ID
    }
    """
    try:
        data = json.loads(request.body)
        question_id = data.get('question_id')
        selected_option_id = data.get('selected_option_id')
        
        # 参数验证
        if not question_id or not selected_option_id:
            return JsonResponse({
                'success': False,
                'message': '题目ID和选项ID不能为空'
            }, status=400)
        
        # 获取题目和选项
        question = Question.objects.get(question_id=question_id)
        selected_option = QuestionOption.objects.get(option_id=selected_option_id)
        
        # 验证选项是否属于该题目
        if selected_option.question != question:
            return JsonResponse({
                'success': False,
                'message': '选项不属于该题目'
            }, status=400)
        
        # 判断答案是否正确（基于选项序号）
        selected_index = selected_option.get_option_index()
        is_correct = (selected_index == question.correct_option_index)
        
        # 计算得分（根据关卡难度）
        base_score = 10  # 基础分数
        difficulty_factor = question.level.difficulty_factor
        score_earned = int(base_score * difficulty_factor) if is_correct else 0
        
        # 记录用户答题
        user_answer = UserAnswer.objects.create(
            user=request.user,
            question=question,
            selected_option=selected_option,
            is_correct=is_correct,
            score_earned=score_earned
        )
        
        # 更新用户总积分
        user_score, created = UserScore.objects.get_or_create(
            user=request.user,
            defaults={'total_score': 0, 'rank': 0}
        )
        user_score.total_score += score_earned
        user_score.save()
        from rewards.utils import award_points
        award_points(request.user, 2, 'challenge_answer', user_answer.answer_log_id)
        
        # 更新用户排名
        update_user_rank()
        
        # 获取正确答案信息
        correct_option = None
        try:
            options = list(QuestionOption.objects.filter(question=question).order_by('option_id'))
            idx = max(1, min(question.correct_option_index, len(options))) - 1
            correct_option = options[idx]
        except Exception:
            correct_option = None
        
        response_data = {
            'is_correct': is_correct,
            'score_earned': score_earned,
            'total_score': user_score.total_score,
            'current_rank': user_score.rank,
            'user_id': request.user.id,
            'username': request.user.username,
            'correct_option_id': (correct_option.option_id if correct_option else None),
            'correct_option_content': (correct_option.content if correct_option else None),
            'selected_option_content': selected_option.content,
            'explanation': get_question_explanation(question_id),
            'difficulty_factor': difficulty_factor
        }
        
        return JsonResponse({
            'success': True,
            'message': '答题提交成功',
            'data': response_data
        })
        
    except (Question.DoesNotExist, QuestionOption.DoesNotExist):
        return JsonResponse({
            'success': False,
            'message': '题目或选项不存在'
        }, status=404)
    except json.JSONDecodeError:
        return JsonResponse({
            'success': False,
            'message': '无效的JSON格式'
        }, status=400)
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'提交答案失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
@login_required
def user_progress_view(request):
    """
    获取用户总体答题进度
    GET /xiangsu/challenge/progress/
    """
    try:
        # 获取所有关卡
        levels = Level.objects.all()
        
        progress_data = []
        total_questions = 0
        total_answered = 0
        total_correct = 0
        
        for level in levels:
            level_questions = Question.objects.filter(level=level)
            level_question_count = level_questions.count()
            
            level_answered = UserAnswer.objects.filter(
                user=request.user,
                question__level=level
            ).values('question').distinct().count()
            
            level_correct = UserAnswer.objects.filter(
                user=request.user,
                question__level=level,
                is_correct=True
            ).count()
            
            progress_data.append({
                'level_id': level.level_id,
                'level_name': level.level_name,
                'total_questions': level_question_count,
                'answered_questions': level_answered,
                'correct_answers': level_correct,
                'completion_rate': round((level_answered / level_question_count) * 100, 2) if level_question_count > 0 else 0,
                'accuracy_rate': round((level_correct / level_answered) * 100, 2) if level_answered > 0 else 0
            })
            
            total_questions += level_question_count
            total_answered += level_answered
            total_correct += level_correct
        
        overall_stats = {
            'total_questions': total_questions,
            'total_answered': total_answered,
            'total_correct': total_correct,
            'overall_completion_rate': round((total_answered / total_questions) * 100, 2) if total_questions > 0 else 0,
            'overall_accuracy_rate': round((total_correct / total_answered) * 100, 2) if total_answered > 0 else 0
        }
        
        return JsonResponse({
            'success': True,
            'data': {
                'levels': progress_data,
                'overall': overall_stats
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取用户进度失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
@login_required
def level_progress_view(request, level_id):
    """
    获取用户指定关卡的详细答题进度
    GET /xiangsu/challenge/progress/{level_id}/
    """
    try:
        level = Level.objects.get(level_id=level_id)
        
        # 获取该关卡的所有题目
        questions = Question.objects.filter(level=level).order_by('question_id')
        q_ids = [q.question_id for q in questions]
        answers_qs = UserAnswer.objects.filter(user=request.user, question_id__in=q_ids).order_by('-answer_log_id')
        ua_map = {}
        for ua in answers_qs:
            if ua.question_id not in ua_map:
                ua_map[ua.question_id] = ua
        options_qs = QuestionOption.objects.filter(question_id__in=q_ids).order_by('option_id')
        options_map = {}
        for opt in options_qs:
            options_map.setdefault(opt.question_id, []).append(opt)
        question_progress = []
        for question in questions:
            options = options_map.get(question.question_id, [])
            option_data = [{
                'option_id': option.option_id,
                'content': option.content,
                'is_correct': (option.get_option_index() == question.correct_option_index)
            } for option in options]
            try:
                correct_idx = question.correct_option_index
                correct_id = options[correct_idx - 1].option_id if 0 < correct_idx <= len(options) else None
            except Exception:
                correct_id = None
            ua = ua_map.get(question.question_id)
            question_progress.append({
                'question_id': question.question_id,
                'content': question.content,
                'options': option_data,
                'is_answered': ua is not None,
                'user_selected_option_id': ua.selected_option.option_id if ua else None,
                'is_correct': ua.is_correct if ua else None,
                'correct_option_id': correct_id
            })
        
        # 计算关卡统计信息
        total_questions = questions.count()
        answered_questions = UserAnswer.objects.filter(
            user=request.user,
            question__level=level
        ).values('question').distinct().count()
        
        correct_answers = UserAnswer.objects.filter(
            user=request.user,
            question__level=level,
            is_correct=True
        ).count()
        
        level_stats = {
            'level_id': level.level_id,
            'level_name': level.level_name,
            'total_questions': total_questions,
            'answered_questions': answered_questions,
            'correct_answers': correct_answers,
            'completion_rate': round((answered_questions / total_questions) * 100, 2) if total_questions > 0 else 0,
            'accuracy_rate': round((correct_answers / answered_questions) * 100, 2) if answered_questions > 0 else 0
        }
        
        return JsonResponse({
            'success': True,
            'data': {
                'level_info': level_stats,
                'questions': question_progress
            }
        })
        
    except Level.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '关卡不存在'
        }, status=404)
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取关卡进度失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
@login_required
def user_stats_view(request):
    """
    获取用户答题统计信息
    GET /xiangsu/challenge/stats/
    """
    try:
        # 获取总体统计
        total_questions = Question.objects.count()
        total_answered = UserAnswer.objects.filter(user=request.user).values('question').distinct().count()
        total_correct = UserAnswer.objects.filter(user=request.user, is_correct=True).count()
        
        # 获取最近答题记录
        recent_answers = UserAnswer.objects.filter(
            user=request.user
        ).order_by('-answer_log_id')[:10]
        
        recent_data = []
        for answer in recent_answers:
            recent_data.append({
                'question_id': answer.question.question_id,
                'question_content': answer.question.content[:50] + '...' if len(answer.question.content) > 50 else answer.question.content,
                'selected_option': answer.selected_option.content,
                'is_correct': answer.is_correct,
                'answer_time': answer.created_at.strftime('%Y-%m-%d %H:%M:%S')
            })
        
        stats_data = {
            'total_questions': total_questions,
            'total_answered': total_answered,
            'total_correct': total_correct,
            'completion_rate': round((total_answered / total_questions) * 100, 2) if total_questions > 0 else 0,
            'accuracy_rate': round((total_correct / total_answered) * 100, 2) if total_answered > 0 else 0,
            'recent_answers': recent_data
        }
        
        return JsonResponse({
            'success': True,
            'data': stats_data
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取用户统计失败: {str(e)}'
        }, status=500)


def get_question_explanation(question_id):
    """
    获取题目解析（可以扩展为从数据库或其他来源获取）
    """
    explanations = {
        1: "这个题目主要考察基础环保知识...",
        2: "正确选择体现了对垃圾分类的理解...",
        # 可以为每个题目添加解析
    }
    return explanations.get(question_id, "解析信息暂无")


def update_user_rank():
    """
    更新所有用户排名
    """
    try:
        # 获取所有用户按积分降序排列
        user_scores = UserScore.objects.order_by('-total_score')
        
        # 更新排名
        rank = 1
        for user_score in user_scores:
            user_score.rank = rank
            user_score.save()
            rank += 1
            
    except Exception as e:
        print(f"更新排名失败: {str(e)}")


@csrf_exempt
@require_http_methods(["GET"])
def leaderboard_view(request):
    """
    获取排行榜
    GET /xiangsu/challenge/leaderboard/
    
    可选参数: page, page_size（默认page=1，page_size=10）；兼容limit
    """
    try:
        # 支持 page/page_size，兼容 limit
        if 'limit' in request.GET and 'page_size' not in request.GET:
            page = 1
            try:
                page_size = int(request.GET.get('limit', 10))
            except Exception:
                page_size = 10
        else:
            page, page_size = get_pagination_params(request, default_page_size=10, max_page_size=100)
        qs = UserScore.objects.order_by('-total_score')
        top_users, meta = paginate_queryset(qs, page, page_size)
        
        leaderboard_data = []
        for user_score in top_users:
            # 获取用户信息
            user_info = {
                'rank': user_score.rank,
                'user_id': user_score.user.id,
                'username': user_score.user.username,
                'total_score': user_score.total_score,
                'last_updated': user_score.last_updated.strftime('%Y-%m-%d %H:%M:%S')
            }
            leaderboard_data.append(user_info)
        
        return JsonResponse({
            'success': True,
            'data': {
                'items': leaderboard_data,
                'meta': meta
            }
        })
        
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取排行榜失败: {str(e)}'
        }, status=500)


@csrf_exempt
@require_http_methods(["GET"])
@login_required
def my_rank_view(request):
    """
    获取当前用户排名信息
    GET /xiangsu/challenge/my_rank/
    """
    try:
        # 获取当前用户积分
        user_score = UserScore.objects.get(user=request.user)
        
        # 获取排名相邻的用户信息
        higher_rank_users = UserScore.objects.filter(
            rank__lt=user_score.rank
        ).order_by('-rank')[:3]
        
        lower_rank_users = UserScore.objects.filter(
            rank__gt=user_score.rank
        ).order_by('rank')[:3]
        
        # 构建排名上下文
        rank_context = {
            'my_rank': {
                'rank': user_score.rank,
                'username': request.user.username,
                'total_score': user_score.total_score,
                'last_updated': user_score.last_updated.strftime('%Y-%m-%d %H:%M:%S')
            },
            'higher_ranks': [{
                'rank': us.rank,
                'username': us.user.username,
                'total_score': us.total_score
            } for us in higher_rank_users],
            'lower_ranks': [{
                'rank': us.rank,
                'username': us.user.username,
                'total_score': us.total_score
            } for us in lower_rank_users]
        }
        
        return JsonResponse({
            'success': True,
            'data': rank_context
        })
        
    except UserScore.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '用户积分信息不存在'
        }, status=404)
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取用户排名失败: {str(e)}'
        }, status=500)


